package jmind.core.support;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Apple Push Notification Service
 * @author weibo-xie
 * 2012-8-8
 */
public class Apns {

    protected static Logger log = LoggerFactory.getLogger(Apns.class);

    /************************************************
     测试推送服务器地址：gateway.sandbox.push.apple.com /2195 
     产品推送服务器地址：gateway.push.apple.com / 2195 

    需要javaPNS_2.2.jar包

     ***************************************************/

    /**

        *这是一个比较简单的推送方法，

        * apple的推送方法

        * @param tokens   iphone手机获取的token

        * @param path 这里是一个.p12格式的文件路径，需要去apple官网申请一个 

        * @param password  p12的密码 此处注意导出的证书密码不能为空因为空密码会报错

        * @param message 推送消息的内容

        * @param badge 应用图标上小红圈上的数值

        * @param sendCount 单发还是群发  true：单发 false：群发

        */

    public void sendpush(List<String> tokens, String path, String password, String message, Integer badge,
            boolean sendCount) {

        try {

            PushNotificationPayload payLoad = PushNotificationPayload.fromJSON(message);

            //payLoad.addAlert(message); // 消息内容

            payLoad.addBadge(badge); // iphone应用图标上小红圈上的数值

            payLoad.addSound("default"); // 铃音 默认

            PushNotificationManager pushManager = new PushNotificationManager();

            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务

            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(path, password, true));

            List<PushedNotification> notifications = new ArrayList<PushedNotification>();

            // 发送push消息

            if (sendCount) {

                log.debug("--------------------------apple 推送 单-------");

                Device device = new BasicDevice();

                device.setToken(tokens.get(0).replace(" ", "").trim());

                PushedNotification notification = pushManager.sendNotification(device, payLoad, true);

                notifications.add(notification);

            } else {

                log.debug("--------------------------apple 推送 群-------");

                List<Device> device = new ArrayList<Device>();

                for (String token : tokens) {

                    device.add(new BasicDevice(token.replace(" ", "").trim()));

                }

                notifications = pushManager.sendNotifications(payLoad, device);

            }

            List<PushedNotification> failedNotifications = PushedNotification.findFailedNotifications(notifications);

            List<PushedNotification> successfulNotifications = PushedNotification
                    .findSuccessfulNotifications(notifications);

            int failed = failedNotifications.size();

            int successful = successfulNotifications.size();

            if (successful > 0 && failed == 0) {

                log.debug("-----All notifications pushed 成功 (" + successfulNotifications.size() + "):");

            } else if (successful == 0 && failed > 0) {

                log.debug("-----All notifications 失败 (" + failedNotifications.size() + "):");

            } else if (successful == 0 && failed == 0) {

                System.out.println("No notifications could be sent, probably because of a critical error");

            } else {

                log.debug("------Some notifications 失败 (" + failedNotifications.size() + "):");

                log.debug("------Others 成功 (" + successfulNotifications.size() + "):");

            }

            // pushManager.stopConnection();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static boolean sendpush(String token, String path, String password, String message, Integer badge,
            boolean production, Map<String, String> param) {

        try {

            PushNotificationPayload payLoad = PushNotificationPayload.combined(message, badge, "default");
            if (param != null) {
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    payLoad.addCustomDictionary(entry.getKey(), entry.getValue());
                }
            }

            PushNotificationManager pushManager = new PushNotificationManager();
            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务
            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(path, password, production));
            // 发送push消息
            Device device = new BasicDevice(token.replace(" ", "").trim());
            PushedNotification notification = pushManager.sendNotification(device, payLoad, true);
            if (notification.getException() != null) {
                notification.getException().printStackTrace();
            }
            return notification.isSuccessful();

        } catch (Exception e) {

            e.printStackTrace();
            return false;

        }
    }

    /**
     * 
     * @param tokens
     * @param path 文件所在绝对路径
     * @param password 密码
     * @param message alert 消息体
     * @param badge 数
     * @param production true ：线上 false：测试
     */
    public static void sendpushs(List<String> tokens, String path, String password, String message, Integer badge,
            boolean production) {

        try {

            PushNotificationPayload payLoad = PushNotificationPayload.combined(message, badge, "default");

            PushNotificationManager pushManager = new PushNotificationManager();

            //true：表示的是产品发布推送服务 false：表示的是产品测试推送服务

            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(path, password, production));

            List<PushedNotification> notifications = new ArrayList<PushedNotification>();

            // 发送push消息
            List<Device> device = new ArrayList<Device>();
            for (String token : tokens) {
                device.add(new BasicDevice(token.replace(" ", "").trim()));
            }

            notifications = pushManager.sendNotifications(payLoad, device);
            List<PushedNotification> failedNotifications = PushedNotification.findFailedNotifications(notifications);
            List<PushedNotification> successfulNotifications = PushedNotification
                    .findSuccessfulNotifications(notifications);
            int failed = failedNotifications.size();
            int successful = successfulNotifications.size();
            if (successful > 0 && failed == 0) {

                log.debug("-----All notifications pushed 成功 (" + successfulNotifications.size() + "):");

            } else if (successful == 0 && failed > 0) {

                log.debug("-----All notifications 失败 (" + failedNotifications.size() + "):");

            } else if (successful == 0 && failed == 0) {

                System.out.println("No notifications could be sent, probably because of a critical error");

            } else {

                log.debug("------Some notifications 失败 (" + failedNotifications.size() + "):");

                log.debug("------Others 成功 (" + successfulNotifications.size() + "):");

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static void main(String[] args) {
        boolean production = true;
        String token = "8928a658 15d08d45 5914840e c017b82c 6af9e8dd b4fba1aa 897be7c3 d49c4a2d";
        //	String token="b00d6855 7ad678f7 d3a0a6c8 3bd1b9c6 db04f93e f85594c3 4668dc80 cab650bf";
        String path = "D:/d/workspace/im20/sc-ppg/src/main/resources/" + (production ? "pro.p12" : "dev.p12");
        String password = "1234567890";
        String message = "亲，新消息";
        int badge = 1;

        Map<String, String> map = new HashMap<String, String>();
        map.put("type", "1");
        map.put("tagId", "1234");
        boolean b = Apns.sendpush(token, path, password, message, badge, production, map);
        System.out.println(b);
    }

}
